package com.zzvcom.template.hibernate;

import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.zzvcom.template.CommonCRUD;
import com.zzvcom.template.ResultPage;
import com.zzvcom.utils.ReflectionUtils;

/**
 * 领域对象的业务管理类基类. 提供了领域对象的简单CRUD方法.
 * 
 * @param <T> 领域对象类型
 * @param <PK> 领域对象的主键类型
 * @author faylai
 */
@Transactional
public abstract class BaseManager<T, PK extends Serializable> implements
        CommonCRUD<T, PK>
{

    protected Logger logger = LoggerFactory.getLogger(getClass());

    protected Class<T> entityClass;
    
    /**
     * 在子类实现的回调函数,为EntityManager提供默认CRUD操作所需的DAO.
     */    
    protected abstract DefaultDao<T, PK> getEntityDao();

    /**
     * 通过子类的范型定义取得领域对象类型Class. eg. public class UserManager extends
     * EntityManager<User, Long>
     */
    @SuppressWarnings("unchecked")
    public BaseManager()
    {
        this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
    }

    public void save(T entity)
    {
        getEntityDao().save(entity);
    }

    @Transactional(readOnly = true)
    public int countByCriteria(DetachedCriteria dc)
    {

        return getEntityDao().countByCriteria(dc);
    }

    public void delete(PK id)
    {
        getEntityDao().delete(id);
    }

    public void delete(T entity)
    {
        getEntityDao().delete(entity);

    }

    @Transactional(readOnly = true)
    public T get(PK id)
    {

        return getEntityDao().get(id);
    }

    @Transactional(readOnly = true)
    public List<T> getAll()
    {
        return getEntityDao().getAll();
    }

    @Transactional(readOnly = true)
    public List getListByCriteria(DetachedCriteria dc, int firstResult,
            int pageSize)
    {

        return getEntityDao().getListByCriteria(dc, firstResult, pageSize);
    }

    @Transactional(readOnly = true)
    public List getListByDetachedCriteria(DetachedCriteria dc)
    {
        return getEntityDao().getListByDetachedCriteria(dc);
    }

    @Transactional(readOnly = true)
    public ResultPage getResultPageByDetachedCriteria(ResultPage page)
    {
        return getEntityDao().getResultPageByDetachedCriteria(page);
    }

    @Transactional(readOnly = true)
    public ResultPage getResultPageByHQL(ResultPage page)
    {
        return getEntityDao().getResultPageByHQL(page);
    }

    public void insert(T entity)
    {
        getEntityDao().insert(entity);
    }

    @Transactional(readOnly = true)
    public List queryByHQL(String hql, int firstResult, int pageSize,
            Object... values)
    {
        return getEntityDao().queryByHQL(hql, firstResult, pageSize, values);
    }

    @Transactional(readOnly = true)
    public List queryByHQL(String hql, Object... values)
    {
        return getEntityDao().queryByHQL(hql, values);
    }

    @Transactional(readOnly = true)
    public Object queryUniqueByDetachedCriteria(DetachedCriteria dc)
    {
        return getEntityDao().queryUniqueByDetachedCriteria(dc);
    }

    @Transactional(readOnly = true)
    public Object queryUniqueByHQL(String hql, Object... values)
    {
        return getEntityDao().queryUniqueByHQL(hql, values);
    }

    public void update(T entity)
    {
        getEntityDao().update(entity);

    }

    public int updateByHQL(String hql, Object... values)
    {
        return getEntityDao().updateByHQL(hql, values);
    }

}
